#ifndef HANDLERACTUALIZACIONPADRE_H_
#define HANDLERACTUALIZACIONPADRE_H_

#include "includes.h"

namespace Toolkit
{

class BloqueBSharp;
class Almacenamiento;
class ControladorAlmacenamientoBSharp;
class WrapperComponente;

class HandlerActualizacionPadre
{
public:
    HandlerActualizacionPadre(ControladorAlmacenamientoBSharp *controlador, const TipoSerializacion &tSerializacion);
    virtual ~HandlerActualizacionPadre();

    void setBloqueActual(const BloqueBSharp *actual,
            const long int &posPadre, const BloqueBSharp *padre,
            const BloqueBSharp *siblingIzquierdo,
            const BloqueBSharp *siblingDerecho);

    /**
     * Se llama cuando no hubo creacion ni eliminacion de nodos, i.e. no hubo
     * UF ni OF, o se solucionaron mediante rebalanceos.
     * Se actualizan en el padre las claves masximas correspondientes a cada nodo.
     */
    void actualizar(Almacenamiento &almacenamiento, const BloqueBSharp *nuevoActual,
            const BloqueBSharp *nuevoIzquierdo, const BloqueBSharp *nuevoDerecho,
            WrapperComponente &wrapper);

    void actualizarPartirDosEnTres(Almacenamiento &almacenamiento,
            const BloqueBSharp &bloqueNuevo, const unsigned long int &posNuevo,
            const BloqueBSharp *nuevoActual, const BloqueBSharp *nuevoIzquierdo,
            const BloqueBSharp *nuevoDerecho, WrapperComponente &wrapper);

    void actualizarPartirUnoEnDos(Almacenamiento &almacenamiento,
            const BloqueBSharp &bloqueNuevo, const unsigned long int &posNuevo,
            const BloqueBSharp *nuevoActual, WrapperComponente &wrapper);

    void actualizarUnirTresEnDos(Almacenamiento &almacenamiento, const BloqueBSharp *nuevoIzquierdo, WrapperComponente &wrapper);

private:
    BloqueBSharp *actual;
    BloqueBSharp *padre;
    BloqueBSharp *siblingIzquierdo;
    BloqueBSharp *siblingDerecho;

    long int posPadre;

    ControladorAlmacenamientoBSharp *controlador;

    TipoSerializacion tSerializacion;


    void reemplazarClaveEnPadre(const BloqueBSharp *bloqueViejo, const BloqueBSharp *bloqueNuevo, BloqueBSharp *padre);
    void propagarNuevoPadre(BloqueBSharp *nuevoPadre, Almacenamiento &almacenamiento, WrapperComponente &wrapper);

};

}

#endif /* HANDLERACTUALIZACIONPADRE_H_ */
